package com.loklok.code.confuse.service;

import cn.hutool.core.map.MapUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.loklok.code.confuse.extension.FeignInterfaceInfoCache;
import com.loklok.code.confuse.model.FeignInterfaceInfo;
import com.loklok.code.confuse.util.ApiUtils;
import com.loklok.code.confuse.util.LocalFileUtils;
import com.loklok.code.confuse.util.PsiFileUtils;
import org.apache.commons.collections.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

public class GenerateUrlMappingService {


    public static void generateUrlMapping(AnActionEvent anActionEvent, String urlsAreaText) {

        FeignInterfaceInfoCache instance = FeignInterfaceInfoCache.getInstance(anActionEvent.getProject());
        // path --- FeignInterfaceInfo 映射
        Map<String, FeignInterfaceInfo> interfaceInfoMap = instance.getFeignInterfaceInfoMap();

        if(MapUtil.isEmpty(interfaceInfoMap)){
            Messages.showErrorDialog("未更新 FeignClient 信息, 请使用插件【update feign info cache】更新", "Error");
            return;
        }

        List<PsiClass> selectedClasses = PsiFileUtils.getSelectedClasses(anActionEvent);
        if(CollectionUtils.isEmpty(selectedClasses)){
            Messages.showErrorDialog("请选择 FeignClient 的类或者包", "Error");
            return;
        }

        VirtualFile projectRoot = ProjectRootManager.getInstance(anActionEvent.getProject()).getContentRoots()[0];
        if (projectRoot == null || !projectRoot.isDirectory()) {
            Messages.showErrorDialog("无法获取项目根目录", "错误");
            return;
        }

        // 方法名 -- 路径 映射
        Map<String, Set<String>> methodNamePathMap = new HashMap<>();

        selectedClasses.stream().forEach(psiClass -> {
            PsiMethod[] methods = psiClass.getMethods();
            if(methods != null && methods.length > 0){
                for (PsiMethod method : methods) {
                    if (!ApiUtils.isRestfulApiMethod(method)) {
                        continue;
                    }
                    String path = ApiUtils.getPath(method);
                    methodNamePathMap.computeIfAbsent(method.getName(), k -> new HashSet<>()).add(path);
                }
            }
        });

        Map<String, String> oldUrlNewUrlMap = new HashMap<>();

        Set<String> inputPaths = Arrays.stream(urlsAreaText.split("[,\n]")) // 使用正则表达式分割逗号和换行
                .map(item -> {
                    String path = item.trim();
                    return path.startsWith("/") ? path : "/" + path;
                }).filter(path -> !path.isEmpty()).collect(Collectors.toSet());

        Set<String> notMatch = new HashSet<>();
        for(String path : inputPaths){
            if(!interfaceInfoMap.containsKey(path)){
                notMatch.add(path);
                continue;
            }

            FeignInterfaceInfo feignInterfaceInfo = interfaceInfoMap.get(path);
            String methodName = feignInterfaceInfo.getMethodName();
            Set<String> pathInMapSet = methodNamePathMap.get(methodName);
            if(pathInMapSet == null){
                continue;
            }
            // 如果 pathInMapSet 只有一个 ，则赋值，如果有多个则遍历 找到符合条件的
            if(pathInMapSet.size() == 1){
                oldUrlNewUrlMap.put(path, pathInMapSet.iterator().next());
            } else if(pathInMapSet.size() > 1){
                pathInMapSet.forEach(pathInMap -> {
                    // 匹配 path 第一部分路径 并且pathInMapSet 包含 这部分的
                    String pathFirstPart = path.split("/")[1];
                    if(pathInMap.contains(pathFirstPart)){
                        oldUrlNewUrlMap.put(path, pathInMap);
                    }
                });
            }
        }


        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : oldUrlNewUrlMap.entrySet()) {
            stringBuilder.append(entry.getKey()).append(" =================> ").append(entry.getValue()).append("\n");
        }

        if(CollectionUtils.isNotEmpty(notMatch)){
            stringBuilder.append("\n\n================以下路径未匹配到方法：==================\n").append(notMatch.stream().collect(Collectors.joining("\n")));
        }

        // 把输出结果写入文件
        LocalFileUtils.writeFile(anActionEvent, projectRoot.getPath(),"url_mapping.txt", stringBuilder.toString(), PlainTextFileType.INSTANCE);
    }

}
